// 因果片段图系统

use std::collections::HashMap;
use crate::symbol_table::SymbolTable;
use crate::utils::{is_common_word, calculate_semantic_similarity};

// 因果边结构体
#[derive(Debug, Clone)]
pub struct CausalEdge {
    pub target: usize,
    pub frequency: f32,
    pub causal_strength: f32,
    pub confidence: f32,
}

// 片段元数据
#[derive(Debug, Clone)]
pub struct FragmentMetadata {
    pub created_at: u64,
    pub last_accessed: u64,
    pub access_count: u64,
    pub importance: f32,
}

// 符号序列片段
pub type Fragment = Vec<usize>;

// 增强的因果片段图
#[derive(Debug)]
pub struct CausalFragmentGraph {
    // 符号ID -> (目标符号ID -> 因果边)
    pub graph: HashMap<usize, HashMap<usize, CausalEdge>>,
    // 存储所有片段
    pub fragments: Vec<Fragment>,
    // 片段元数据
    pub fragment_metadata: Vec<FragmentMetadata>,
    // 当前时间
    pub current_time: u64,
    // 总转换次数
    pub total_transitions: u64,
}

impl CausalFragmentGraph {
    pub fn new() -> Self {
        Self {
            graph: HashMap::new(),
            fragments: Vec::new(),
            fragment_metadata: Vec::new(),
            current_time: 0,
            total_transitions: 0,
        }
    }
    
    // 添加符号序列片段
    pub fn add_fragment(&mut self, fragment: Fragment) {
        if fragment.len() < 2 {
            return;
        }
        
        // 更新时间
        self.current_time += 1;
        
        // 添加到片段列表
        self.fragments.push(fragment.clone());
        
        // 创建片段元数据
        let metadata = FragmentMetadata {
            created_at: self.current_time,
            last_accessed: self.current_time,
            access_count: 1,
            importance: self.calculate_fragment_importance(&fragment),
        };
        self.fragment_metadata.push(metadata);
        
        // 更新因果图
        for i in 0..fragment.len() - 1 {
            let source = fragment[i];
            let target = fragment[i + 1];
            
            // 获取或创建源节点的边映射
            let edges = self.graph.entry(source).or_insert_with(HashMap::new);
            
            // 获取或创建因果边
            let edge = edges.entry(target).or_insert_with(|| CausalEdge {
                target,
                frequency: 0.0,
                causal_strength: 0.0,
                confidence: 0.0,
            });
            
            // 更新边的属性
            edge.frequency += 1.0;
            edge.causal_strength += 1.0; // 简单的线性增强
            edge.confidence = (edge.frequency / self.total_transitions as f32).min(1.0);
            
            self.total_transitions += 1;
        }
    }
    
    // 提取主题词
    pub fn extract_topics(&self, symbol_table: &SymbolTable, top_n: usize) -> Vec<usize> {
        let mut symbol_importance = HashMap::new();
        
        // 计算每个符号的重要性
        for (source_id, edges) in &self.graph {
            let importance = edges.values()
                .map(|e| e.causal_strength * e.confidence)
                .sum::<f32>();
            
            symbol_importance.insert(*source_id, importance);
        }
        
        // 按重要性排序
        let mut symbols: Vec<_> = symbol_importance.into_iter().collect();
        symbols.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap());
        
        // 过滤常见词并返回前top_n个
        symbols.into_iter()
            .filter_map(|(id, _)| {
                if let Some(text) = symbol_table.get_text(id) {
                    if !is_common_word(text) {
                        Some(id)
                    } else {
                        None
                    }
                } else {
                    None
                }
            })
            .take(top_n)
            .collect()
    }
    
    // 计算片段重要性
    pub fn calculate_fragment_importance(&self, fragment: &Fragment) -> f32 {
        if fragment.is_empty() {
            return 0.0;
        }
        
        let mut importance = 0.0;
        
        // 计算片段中符号的平均重要性
        for &symbol_id in fragment {
            if let Some(edges) = self.graph.get(&symbol_id) {
                let symbol_importance = edges.values()
                    .map(|e| e.causal_strength * e.confidence)
                    .sum::<f32>();
                importance += symbol_importance;
            }
        }
        
        importance / fragment.len() as f32
    }
    
    // 更新语义网络
    pub fn update_semantic_network(&mut self, fragment: &Fragment, symbol_table: &mut SymbolTable) {
        // 更新符号之间的语义关系
        for i in 0..fragment.len() {
            for j in i + 1..fragment.len() {
                let id1 = fragment[i];
                let id2 = fragment[j];
                
                // 计算关系强度（基于距离）
                let distance = (j - i) as f32;
                let strength = 1.0 / distance;
                
                // 更新符号表中的关系
                symbol_table.update_symbol_relation(id1, id2, strength);
                symbol_table.update_symbol_relation(id2, id1, strength);
            }
        }
    }
    
    // 应用时间衰减
    pub fn apply_time_decay(&mut self, decay_factor: f32) {
        // 对因果边应用时间衰减
        for edges in self.graph.values_mut() {
            for edge in edges.values_mut() {
                edge.frequency *= decay_factor;
                edge.causal_strength *= decay_factor;
            }
        }
        
        // 对片段元数据应用时间衰减
        for metadata in &mut self.fragment_metadata {
            metadata.importance *= decay_factor;
        }
    }
    
    // 预测下一个符号
    pub fn predict_next(&self, current: usize, context: &[usize], symbol_table: &SymbolTable) -> Option<usize> {
        if let Some(edges) = self.graph.get(&current) {
            // 基于频率和因果强度的加权选择
            let mut candidates: Vec<_> = edges.iter()
                .map(|(&target, edge)| {
                    let mut score = edge.frequency * edge.causal_strength * edge.confidence;
                    
                    // 考虑上下文相关性
                    if !context.is_empty() {
                        // 简化上下文相关性计算，避免创建大型HashMap
                        let context_relevance = if context.contains(&target) {
                            0.5 // 如果目标在上下文中，给予中等相关性
                        } else {
                            0.1 // 否则给予低相关性
                        };
                        score *= 1.0 + context_relevance;
                    }
                    
                    (target, score)
                })
                .collect();
            
            // 按分数排序
            candidates.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap());
            
            // 返回得分最高的候选
            candidates.first().map(|&(target, _)| target)
        } else {
            None
        }
    }
    
    // 获取与主题相关的片段
    pub fn get_fragments_by_topic(&self, topic: usize, _min_relevance: f32) -> Vec<&Fragment> {
        self.fragments.iter()
            .filter(|fragment| {
                fragment.contains(&topic) || 
                fragment.iter().any(|&_id| {
                    // 这里可以添加更复杂的相关性计算
                    false // 简化实现
                })
            })
            .collect()
    }
    
    // 获取以指定符号序列开头的片段
    pub fn get_fragments_starting_with(&self, prefix: &[usize]) -> Vec<&Fragment> {
        if prefix.is_empty() {
            return Vec::new();
        }
        
        self.fragments.iter()
            .filter(|fragment| {
                fragment.len() >= prefix.len() && 
                fragment.iter().zip(prefix.iter()).all(|(a, b)| a == b)
            })
            .collect()
    }
    
    // 获取匹配的片段
    pub fn get_matching_fragments(&self, context: &[usize], min_match_length: usize) -> Vec<&Fragment> {
        if context.is_empty() || min_match_length == 0 {
            return Vec::new();
        }
        
        self.fragments.iter()
            .filter(|fragment| {
                // 检查片段中是否包含与上下文匹配的子序列
                for i in 0..=context.len().saturating_sub(min_match_length) {
                    for j in 0..=fragment.len().saturating_sub(min_match_length) {
                        let mut match_length = 0;
                        let max_match = min_match_length.min(context.len() - i).min(fragment.len() - j);
                        
                        for k in 0..max_match {
                            if context[i + k] == fragment[j + k] {
                                match_length += 1;
                            } else {
                                break;
                            }
                        }
                        
                        if match_length >= min_match_length {
                            return true;
                        }
                    }
                }
                false
            })
            .collect()
    }
    
    // 获取语义相关的片段
    pub fn get_semantically_related_fragments(&self, context: &[usize], symbol_table: &SymbolTable, min_relevance: f32) -> Vec<&Fragment> {
        if context.is_empty() {
            return Vec::new();
        }
        
        self.fragments.iter()
            .filter(|fragment| {
                let relevance = calculate_fragment_relevance(fragment, context, symbol_table);
                relevance >= min_relevance
            })
            .collect()
    }
    
    // 更新片段访问
    pub fn update_fragment_access(&mut self, fragment_id: usize) {
        if fragment_id < self.fragment_metadata.len() && fragment_id < self.fragments.len() {
            // 先获取不可变引用计算重要性
            let importance = self.calculate_fragment_importance(&self.fragments[fragment_id]);
            let current_time = self.current_time;
            
            // 然后获取可变引用更新元数据
            let metadata = &mut self.fragment_metadata[fragment_id];
            metadata.last_accessed = current_time;
            metadata.access_count += 1;
            metadata.importance = importance * (1.0 + metadata.access_count as f32 * 0.1);
        }
    }
}

// 计算片段与上下文的相关性
fn calculate_fragment_relevance(fragment: &[usize], context: &[usize], symbol_table: &SymbolTable) -> f32 {
    if fragment.is_empty() || context.is_empty() {
        return 0.0;
    }
    
    let mut relevance = 0.0;
    
    for &fragment_symbol in fragment {
        for &context_symbol in context {
            // 直接匹配
            if fragment_symbol == context_symbol {
                relevance += 1.0;
            } else {
                // 语义相关
                let relation_strength = symbol_table.get_relation_strength(fragment_symbol, context_symbol);
                relevance += relation_strength;
            }
        }
    }
    
    // 归一化
    relevance / (fragment.len() * context.len()) as f32
}